// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

/////////////////////////////////////////////////////////////////////////////
////
// This file was auto-generated by a tool at 2022-04-27 09:53:39
//
// It is recommended you DO NOT directly edit this file but instead edit
// the code-generator that generated this source file instead.
/////////////////////////////////////////////////////////////////////////////

#ifndef BITONIC_SORT_AVX2_INT32_T_H
#define BITONIC_SORT_AVX2_INT32_T_H

#ifdef __GNUC__
#ifdef __clang__
#pragma clang attribute push (__attribute__((target("avx2"))), apply_to = any(function))
#else
#pragma GCC push_options
#pragma GCC target("avx2")
#endif
#endif

#include <immintrin.h>
#include "bitonic_sort.h"

#define i2d _mm256_castsi256_pd
#define d2i _mm256_castpd_si256
#define i2s _mm256_castsi256_ps
#define s2i _mm256_castps_si256
#define s2d _mm256_castps_pd
#define d2s _mm256_castpd_ps

namespace vxsort {
namespace smallsort {

extern "C" const uint8_t mask_table_4[M4_SIZE];
extern "C" const uint8_t mask_table_8[M8_SIZE];

template<> struct bitonic<int32_t, AVX2> {
    static const int N = 8;
    static constexpr int32_t MAX = std::numeric_limits<int32_t>::Max();
public:

    static INLINE void sort_01v_ascending(__m256i& d01) {
            __m256i  min, max, s;

            s = _mm256_shuffle_epi32(d01, 0xB1);
            
            min = _mm256_min_epi32(s, d01);
            max = _mm256_max_epi32(s, d01);
            d01 = _mm256_blend_epi32(min, max, 0xAA);

            s = _mm256_shuffle_epi32(d01, 0x1B);
            
            min = _mm256_min_epi32(s, d01);
            max = _mm256_max_epi32(s, d01);
            d01 = _mm256_blend_epi32(min, max, 0xCC);

            s = _mm256_shuffle_epi32(d01, 0xB1);
            
            min = _mm256_min_epi32(s, d01);
            max = _mm256_max_epi32(s, d01);
            d01 = _mm256_blend_epi32(min, max, 0xAA);

            s = d2i(_mm256_permute4x64_pd(i2d(_mm256_shuffle_epi32(d01, 0x1B)), 0x4E));
            min = _mm256_min_epi32(s, d01);
            max = _mm256_max_epi32(s, d01);
            d01 = _mm256_blend_epi32(min, max, 0xF0);

            s = _mm256_shuffle_epi32(d01, 0x4E);
            min = _mm256_min_epi32(s, d01);
            max = _mm256_max_epi32(s, d01);
            d01 = _mm256_blend_epi32(min, max, 0xCC);

            s = _mm256_shuffle_epi32(d01, 0xB1);
            min = _mm256_min_epi32(s, d01);
            max = _mm256_max_epi32(s, d01);
            d01 = _mm256_blend_epi32(min, max, 0xAA);
}
    static INLINE void sort_01v_merge_ascending(__m256i& d01) {
            __m256i  min, max, s;

            s = d2i(_mm256_permute4x64_pd(i2d(d01), 0x4E));
            min = _mm256_min_epi32(s, d01);
            max = _mm256_max_epi32(s, d01);
            d01 = _mm256_blend_epi32(min, max, 0xF0);

            s = _mm256_shuffle_epi32(d01, 0x4E);
            
            min = _mm256_min_epi32(s, d01);
            max = _mm256_max_epi32(s, d01);
            d01 = _mm256_blend_epi32(min, max, 0xCC);

            s = _mm256_shuffle_epi32(d01, 0xB1);
            
            min = _mm256_min_epi32(s, d01);
            max = _mm256_max_epi32(s, d01);
            d01 = _mm256_blend_epi32(min, max, 0xAA);
    }
    static INLINE void sort_01v_descending(__m256i& d01) {
            __m256i  min, max, s;

            s = _mm256_shuffle_epi32(d01, 0xB1);
            
            min = _mm256_min_epi32(s, d01);
            max = _mm256_max_epi32(s, d01);
            d01 = _mm256_blend_epi32(max, min, 0xAA);

            s = _mm256_shuffle_epi32(d01, 0x1B);
            
            min = _mm256_min_epi32(s, d01);
            max = _mm256_max_epi32(s, d01);
            d01 = _mm256_blend_epi32(max, min, 0xCC);

            s = _mm256_shuffle_epi32(d01, 0xB1);
            
            min = _mm256_min_epi32(s, d01);
            max = _mm256_max_epi32(s, d01);
            d01 = _mm256_blend_epi32(max, min, 0xAA);

            s = d2i(_mm256_permute4x64_pd(i2d(_mm256_shuffle_epi32(d01, 0x1B)), 0x4E));
            min = _mm256_min_epi32(s, d01);
            max = _mm256_max_epi32(s, d01);
            d01 = _mm256_blend_epi32(max, min, 0xF0);

            s = _mm256_shuffle_epi32(d01, 0x4E);
            min = _mm256_min_epi32(s, d01);
            max = _mm256_max_epi32(s, d01);
            d01 = _mm256_blend_epi32(max, min, 0xCC);

            s = _mm256_shuffle_epi32(d01, 0xB1);
            min = _mm256_min_epi32(s, d01);
            max = _mm256_max_epi32(s, d01);
            d01 = _mm256_blend_epi32(max, min, 0xAA);
}
    static INLINE void sort_01v_merge_descending(__m256i& d01) {
            __m256i  min, max, s;

            s = d2i(_mm256_permute4x64_pd(i2d(d01), 0x4E));
            min = _mm256_min_epi32(s, d01);
            max = _mm256_max_epi32(s, d01);
            d01 = _mm256_blend_epi32(max, min, 0xF0);

            s = _mm256_shuffle_epi32(d01, 0x4E);
            
            min = _mm256_min_epi32(s, d01);
            max = _mm256_max_epi32(s, d01);
            d01 = _mm256_blend_epi32(max, min, 0xCC);

            s = _mm256_shuffle_epi32(d01, 0xB1);
            
            min = _mm256_min_epi32(s, d01);
            max = _mm256_max_epi32(s, d01);
            d01 = _mm256_blend_epi32(max, min, 0xAA);
    }
    static INLINE void sort_02v_ascending(__m256i& d01, __m256i& d02) {
        __m256i  tmp;

        sort_01v_ascending(d01);
        sort_01v_descending(d02);

        tmp = d02;
        
        d02 = _mm256_max_epi32(d01, d02);
        d01 = _mm256_min_epi32(d01, tmp);

        sort_01v_merge_ascending(d01);
        sort_01v_merge_ascending(d02);
    }
    static INLINE void sort_02v_descending(__m256i& d01, __m256i& d02) {
        __m256i  tmp;

        sort_01v_descending(d01);
        sort_01v_ascending(d02);

        tmp = d02;
        
        d02 = _mm256_max_epi32(d01, d02);
        d01 = _mm256_min_epi32(d01, tmp);

        sort_01v_merge_descending(d01);
        sort_01v_merge_descending(d02);
    }
    static INLINE void sort_02v_merge_ascending(__m256i& d01, __m256i& d02) {
        __m256i  tmp;

        tmp = d01;
        
        d01 = _mm256_min_epi32(d02, d01);
        
        d02 = _mm256_max_epi32(d02, tmp);

        sort_01v_merge_ascending(d01);
        sort_01v_merge_ascending(d02);
    }
    static INLINE void sort_02v_merge_descending(__m256i& d01, __m256i& d02) {
        __m256i  tmp;

        tmp = d01;
        
        d01 = _mm256_min_epi32(d02, d01);
        
        d02 = _mm256_max_epi32(d02, tmp);

        sort_01v_merge_descending(d01);
        sort_01v_merge_descending(d02);
    }
    static INLINE void sort_03v_ascending(__m256i& d01, __m256i& d02, __m256i& d03) {
        __m256i  tmp;

        sort_02v_ascending(d01, d02);
        sort_01v_descending(d03);

        tmp = d03;
        
        d03 = _mm256_max_epi32(d02, d03);
        d02 = _mm256_min_epi32(d02, tmp);

        sort_02v_merge_ascending(d01, d02);
        sort_01v_merge_ascending(d03);
    }
    static INLINE void sort_03v_descending(__m256i& d01, __m256i& d02, __m256i& d03) {
        __m256i  tmp;

        sort_02v_descending(d01, d02);
        sort_01v_ascending(d03);

        tmp = d03;
        
        d03 = _mm256_max_epi32(d02, d03);
        d02 = _mm256_min_epi32(d02, tmp);

        sort_02v_merge_descending(d01, d02);
        sort_01v_merge_descending(d03);
    }
    static INLINE void sort_03v_merge_ascending(__m256i& d01, __m256i& d02, __m256i& d03) {
        __m256i  tmp;

        tmp = d01;
        
        d01 = _mm256_min_epi32(d03, d01);
        
        d03 = _mm256_max_epi32(d03, tmp);

        sort_02v_merge_ascending(d01, d02);
        sort_01v_merge_ascending(d03);
    }
    static INLINE void sort_03v_merge_descending(__m256i& d01, __m256i& d02, __m256i& d03) {
        __m256i  tmp;

        tmp = d01;
        
        d01 = _mm256_min_epi32(d03, d01);
        
        d03 = _mm256_max_epi32(d03, tmp);

        sort_02v_merge_descending(d01, d02);
        sort_01v_merge_descending(d03);
    }
    static NOINLINE void sort_04v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04) {
        __m256i  tmp;

        sort_02v_ascending(d01, d02);
        sort_02v_descending(d03, d04);

        tmp = d03;
        
        d03 = _mm256_max_epi32(d02, d03);
        d02 = _mm256_min_epi32(d02, tmp);

        tmp = d04;
        
        d04 = _mm256_max_epi32(d01, d04);
        d01 = _mm256_min_epi32(d01, tmp);

        sort_02v_merge_ascending(d01, d02);
        sort_02v_merge_ascending(d03, d04);
    }
    static NOINLINE void sort_04v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04) {
        __m256i  tmp;

        sort_02v_descending(d01, d02);
        sort_02v_ascending(d03, d04);

        tmp = d03;
        
        d03 = _mm256_max_epi32(d02, d03);
        d02 = _mm256_min_epi32(d02, tmp);

        tmp = d04;
        
        d04 = _mm256_max_epi32(d01, d04);
        d01 = _mm256_min_epi32(d01, tmp);

        sort_02v_merge_descending(d01, d02);
        sort_02v_merge_descending(d03, d04);
    }
    static NOINLINE void sort_04v_merge_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04) {
        __m256i  tmp;

        tmp = d01;
        
        d01 = _mm256_min_epi32(d03, d01);
        
        d03 = _mm256_max_epi32(d03, tmp);

        tmp = d02;
        
        d02 = _mm256_min_epi32(d04, d02);
        
        d04 = _mm256_max_epi32(d04, tmp);

        sort_02v_merge_ascending(d01, d02);
        sort_02v_merge_ascending(d03, d04);
    }
    static NOINLINE void sort_04v_merge_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04) {
        __m256i  tmp;

        tmp = d01;
        
        d01 = _mm256_min_epi32(d03, d01);
        
        d03 = _mm256_max_epi32(d03, tmp);

        tmp = d02;
        
        d02 = _mm256_min_epi32(d04, d02);
        
        d04 = _mm256_max_epi32(d04, tmp);

        sort_02v_merge_descending(d01, d02);
        sort_02v_merge_descending(d03, d04);
    }
    static INLINE void sort_05v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05) {
        __m256i  tmp;

        sort_04v_ascending(d01, d02, d03, d04);
        sort_01v_descending(d05);

        tmp = d05;
        
        d05 = _mm256_max_epi32(d04, d05);
        d04 = _mm256_min_epi32(d04, tmp);

        sort_04v_merge_ascending(d01, d02, d03, d04);
        sort_01v_merge_ascending(d05);
    }
    static INLINE void sort_05v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05) {
        __m256i  tmp;

        sort_04v_descending(d01, d02, d03, d04);
        sort_01v_ascending(d05);

        tmp = d05;
        
        d05 = _mm256_max_epi32(d04, d05);
        d04 = _mm256_min_epi32(d04, tmp);

        sort_04v_merge_descending(d01, d02, d03, d04);
        sort_01v_merge_descending(d05);
    }
    static INLINE void sort_05v_merge_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05) {
        __m256i  tmp;

        tmp = d01;
        
        d01 = _mm256_min_epi32(d05, d01);
        
        d05 = _mm256_max_epi32(d05, tmp);

        sort_04v_merge_ascending(d01, d02, d03, d04);
        sort_01v_merge_ascending(d05);
    }
    static INLINE void sort_05v_merge_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05) {
        __m256i  tmp;

        tmp = d01;
        
        d01 = _mm256_min_epi32(d05, d01);
        
        d05 = _mm256_max_epi32(d05, tmp);

        sort_04v_merge_descending(d01, d02, d03, d04);
        sort_01v_merge_descending(d05);
    }
    static INLINE void sort_06v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06) {
        __m256i  tmp;

        sort_04v_ascending(d01, d02, d03, d04);
        sort_02v_descending(d05, d06);

        tmp = d05;
        
        d05 = _mm256_max_epi32(d04, d05);
        d04 = _mm256_min_epi32(d04, tmp);

        tmp = d06;
        
        d06 = _mm256_max_epi32(d03, d06);
        d03 = _mm256_min_epi32(d03, tmp);

        sort_04v_merge_ascending(d01, d02, d03, d04);
        sort_02v_merge_ascending(d05, d06);
    }
    static INLINE void sort_06v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06) {
        __m256i  tmp;

        sort_04v_descending(d01, d02, d03, d04);
        sort_02v_ascending(d05, d06);

        tmp = d05;
        
        d05 = _mm256_max_epi32(d04, d05);
        d04 = _mm256_min_epi32(d04, tmp);

        tmp = d06;
        
        d06 = _mm256_max_epi32(d03, d06);
        d03 = _mm256_min_epi32(d03, tmp);

        sort_04v_merge_descending(d01, d02, d03, d04);
        sort_02v_merge_descending(d05, d06);
    }
    static INLINE void sort_06v_merge_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06) {
        __m256i  tmp;

        tmp = d01;
        
        d01 = _mm256_min_epi32(d05, d01);
        
        d05 = _mm256_max_epi32(d05, tmp);

        tmp = d02;
        
        d02 = _mm256_min_epi32(d06, d02);
        
        d06 = _mm256_max_epi32(d06, tmp);

        sort_04v_merge_ascending(d01, d02, d03, d04);
        sort_02v_merge_ascending(d05, d06);
    }
    static INLINE void sort_06v_merge_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06) {
        __m256i  tmp;

        tmp = d01;
        
        d01 = _mm256_min_epi32(d05, d01);
        
        d05 = _mm256_max_epi32(d05, tmp);

        tmp = d02;
        
        d02 = _mm256_min_epi32(d06, d02);
        
        d06 = _mm256_max_epi32(d06, tmp);

        sort_04v_merge_descending(d01, d02, d03, d04);
        sort_02v_merge_descending(d05, d06);
    }
    static INLINE void sort_07v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07) {
        __m256i  tmp;

        sort_04v_ascending(d01, d02, d03, d04);
        sort_03v_descending(d05, d06, d07);

        tmp = d05;
        
        d05 = _mm256_max_epi32(d04, d05);
        d04 = _mm256_min_epi32(d04, tmp);

        tmp = d06;
        
        d06 = _mm256_max_epi32(d03, d06);
        d03 = _mm256_min_epi32(d03, tmp);

        tmp = d07;
        
        d07 = _mm256_max_epi32(d02, d07);
        d02 = _mm256_min_epi32(d02, tmp);

        sort_04v_merge_ascending(d01, d02, d03, d04);
        sort_03v_merge_ascending(d05, d06, d07);
    }
    static INLINE void sort_07v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07) {
        __m256i  tmp;

        sort_04v_descending(d01, d02, d03, d04);
        sort_03v_ascending(d05, d06, d07);

        tmp = d05;
        
        d05 = _mm256_max_epi32(d04, d05);
        d04 = _mm256_min_epi32(d04, tmp);

        tmp = d06;
        
        d06 = _mm256_max_epi32(d03, d06);
        d03 = _mm256_min_epi32(d03, tmp);

        tmp = d07;
        
        d07 = _mm256_max_epi32(d02, d07);
        d02 = _mm256_min_epi32(d02, tmp);

        sort_04v_merge_descending(d01, d02, d03, d04);
        sort_03v_merge_descending(d05, d06, d07);
    }
    static INLINE void sort_07v_merge_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07) {
        __m256i  tmp;

        tmp = d01;
        
        d01 = _mm256_min_epi32(d05, d01);
        
        d05 = _mm256_max_epi32(d05, tmp);

        tmp = d02;
        
        d02 = _mm256_min_epi32(d06, d02);
        
        d06 = _mm256_max_epi32(d06, tmp);

        tmp = d03;
        
        d03 = _mm256_min_epi32(d07, d03);
        
        d07 = _mm256_max_epi32(d07, tmp);

        sort_04v_merge_ascending(d01, d02, d03, d04);
        sort_03v_merge_ascending(d05, d06, d07);
    }
    static INLINE void sort_07v_merge_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07) {
        __m256i  tmp;

        tmp = d01;
        
        d01 = _mm256_min_epi32(d05, d01);
        
        d05 = _mm256_max_epi32(d05, tmp);

        tmp = d02;
        
        d02 = _mm256_min_epi32(d06, d02);
        
        d06 = _mm256_max_epi32(d06, tmp);

        tmp = d03;
        
        d03 = _mm256_min_epi32(d07, d03);
        
        d07 = _mm256_max_epi32(d07, tmp);

        sort_04v_merge_descending(d01, d02, d03, d04);
        sort_03v_merge_descending(d05, d06, d07);
    }
    static NOINLINE void sort_08v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08) {
        __m256i  tmp;

        sort_04v_ascending(d01, d02, d03, d04);
        sort_04v_descending(d05, d06, d07, d08);

        tmp = d05;
        
        d05 = _mm256_max_epi32(d04, d05);
        d04 = _mm256_min_epi32(d04, tmp);

        tmp = d06;
        
        d06 = _mm256_max_epi32(d03, d06);
        d03 = _mm256_min_epi32(d03, tmp);

        tmp = d07;
        
        d07 = _mm256_max_epi32(d02, d07);
        d02 = _mm256_min_epi32(d02, tmp);

        tmp = d08;
        
        d08 = _mm256_max_epi32(d01, d08);
        d01 = _mm256_min_epi32(d01, tmp);

        sort_04v_merge_ascending(d01, d02, d03, d04);
        sort_04v_merge_ascending(d05, d06, d07, d08);
    }
    static NOINLINE void sort_08v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08) {
        __m256i  tmp;

        sort_04v_descending(d01, d02, d03, d04);
        sort_04v_ascending(d05, d06, d07, d08);

        tmp = d05;
        
        d05 = _mm256_max_epi32(d04, d05);
        d04 = _mm256_min_epi32(d04, tmp);

        tmp = d06;
        
        d06 = _mm256_max_epi32(d03, d06);
        d03 = _mm256_min_epi32(d03, tmp);

        tmp = d07;
        
        d07 = _mm256_max_epi32(d02, d07);
        d02 = _mm256_min_epi32(d02, tmp);

        tmp = d08;
        
        d08 = _mm256_max_epi32(d01, d08);
        d01 = _mm256_min_epi32(d01, tmp);

        sort_04v_merge_descending(d01, d02, d03, d04);
        sort_04v_merge_descending(d05, d06, d07, d08);
    }
    static NOINLINE void sort_08v_merge_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08) {
        __m256i  tmp;

        tmp = d01;
        
        d01 = _mm256_min_epi32(d05, d01);
        
        d05 = _mm256_max_epi32(d05, tmp);

        tmp = d02;
        
        d02 = _mm256_min_epi32(d06, d02);
        
        d06 = _mm256_max_epi32(d06, tmp);

        tmp = d03;
        
        d03 = _mm256_min_epi32(d07, d03);
        
        d07 = _mm256_max_epi32(d07, tmp);

        tmp = d04;
        
        d04 = _mm256_min_epi32(d08, d04);
        
        d08 = _mm256_max_epi32(d08, tmp);

        sort_04v_merge_ascending(d01, d02, d03, d04);
        sort_04v_merge_ascending(d05, d06, d07, d08);
    }
    static NOINLINE void sort_08v_merge_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08) {
        __m256i  tmp;

        tmp = d01;
        
        d01 = _mm256_min_epi32(d05, d01);
        
        d05 = _mm256_max_epi32(d05, tmp);

        tmp = d02;
        
        d02 = _mm256_min_epi32(d06, d02);
        
        d06 = _mm256_max_epi32(d06, tmp);

        tmp = d03;
        
        d03 = _mm256_min_epi32(d07, d03);
        
        d07 = _mm256_max_epi32(d07, tmp);

        tmp = d04;
        
        d04 = _mm256_min_epi32(d08, d04);
        
        d08 = _mm256_max_epi32(d08, tmp);

        sort_04v_merge_descending(d01, d02, d03, d04);
        sort_04v_merge_descending(d05, d06, d07, d08);
    }
    static INLINE void sort_09v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09) {
        __m256i  tmp;

        sort_08v_ascending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_01v_descending(d09);

        tmp = d09;
        
        d09 = _mm256_max_epi32(d08, d09);
        d08 = _mm256_min_epi32(d08, tmp);

        sort_08v_merge_ascending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_01v_merge_ascending(d09);
    }
    static INLINE void sort_09v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09) {
        __m256i  tmp;

        sort_08v_descending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_01v_ascending(d09);

        tmp = d09;
        
        d09 = _mm256_max_epi32(d08, d09);
        d08 = _mm256_min_epi32(d08, tmp);

        sort_08v_merge_descending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_01v_merge_descending(d09);
    }
    static INLINE void sort_10v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10) {
        __m256i  tmp;

        sort_08v_ascending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_02v_descending(d09, d10);

        tmp = d09;
        
        d09 = _mm256_max_epi32(d08, d09);
        d08 = _mm256_min_epi32(d08, tmp);

        tmp = d10;
        
        d10 = _mm256_max_epi32(d07, d10);
        d07 = _mm256_min_epi32(d07, tmp);

        sort_08v_merge_ascending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_02v_merge_ascending(d09, d10);
    }
    static INLINE void sort_10v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10) {
        __m256i  tmp;

        sort_08v_descending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_02v_ascending(d09, d10);

        tmp = d09;
        
        d09 = _mm256_max_epi32(d08, d09);
        d08 = _mm256_min_epi32(d08, tmp);

        tmp = d10;
        
        d10 = _mm256_max_epi32(d07, d10);
        d07 = _mm256_min_epi32(d07, tmp);

        sort_08v_merge_descending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_02v_merge_descending(d09, d10);
    }
    static INLINE void sort_11v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11) {
        __m256i  tmp;

        sort_08v_ascending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_03v_descending(d09, d10, d11);

        tmp = d09;
        
        d09 = _mm256_max_epi32(d08, d09);
        d08 = _mm256_min_epi32(d08, tmp);

        tmp = d10;
        
        d10 = _mm256_max_epi32(d07, d10);
        d07 = _mm256_min_epi32(d07, tmp);

        tmp = d11;
        
        d11 = _mm256_max_epi32(d06, d11);
        d06 = _mm256_min_epi32(d06, tmp);

        sort_08v_merge_ascending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_03v_merge_ascending(d09, d10, d11);
    }
    static INLINE void sort_11v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11) {
        __m256i  tmp;

        sort_08v_descending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_03v_ascending(d09, d10, d11);

        tmp = d09;
        
        d09 = _mm256_max_epi32(d08, d09);
        d08 = _mm256_min_epi32(d08, tmp);

        tmp = d10;
        
        d10 = _mm256_max_epi32(d07, d10);
        d07 = _mm256_min_epi32(d07, tmp);

        tmp = d11;
        
        d11 = _mm256_max_epi32(d06, d11);
        d06 = _mm256_min_epi32(d06, tmp);

        sort_08v_merge_descending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_03v_merge_descending(d09, d10, d11);
    }
    static NOINLINE void sort_12v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12) {
        __m256i  tmp;

        sort_08v_ascending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_04v_descending(d09, d10, d11, d12);

        tmp = d09;
        
        d09 = _mm256_max_epi32(d08, d09);
        d08 = _mm256_min_epi32(d08, tmp);

        tmp = d10;
        
        d10 = _mm256_max_epi32(d07, d10);
        d07 = _mm256_min_epi32(d07, tmp);

        tmp = d11;
        
        d11 = _mm256_max_epi32(d06, d11);
        d06 = _mm256_min_epi32(d06, tmp);

        tmp = d12;
        
        d12 = _mm256_max_epi32(d05, d12);
        d05 = _mm256_min_epi32(d05, tmp);

        sort_08v_merge_ascending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_04v_merge_ascending(d09, d10, d11, d12);
    }
    static NOINLINE void sort_12v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12) {
        __m256i  tmp;

        sort_08v_descending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_04v_ascending(d09, d10, d11, d12);

        tmp = d09;
        
        d09 = _mm256_max_epi32(d08, d09);
        d08 = _mm256_min_epi32(d08, tmp);

        tmp = d10;
        
        d10 = _mm256_max_epi32(d07, d10);
        d07 = _mm256_min_epi32(d07, tmp);

        tmp = d11;
        
        d11 = _mm256_max_epi32(d06, d11);
        d06 = _mm256_min_epi32(d06, tmp);

        tmp = d12;
        
        d12 = _mm256_max_epi32(d05, d12);
        d05 = _mm256_min_epi32(d05, tmp);

        sort_08v_merge_descending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_04v_merge_descending(d09, d10, d11, d12);
    }
    static INLINE void sort_13v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12, __m256i& d13) {
        __m256i  tmp;

        sort_08v_ascending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_05v_descending(d09, d10, d11, d12, d13);

        tmp = d09;
        
        d09 = _mm256_max_epi32(d08, d09);
        d08 = _mm256_min_epi32(d08, tmp);

        tmp = d10;
        
        d10 = _mm256_max_epi32(d07, d10);
        d07 = _mm256_min_epi32(d07, tmp);

        tmp = d11;
        
        d11 = _mm256_max_epi32(d06, d11);
        d06 = _mm256_min_epi32(d06, tmp);

        tmp = d12;
        
        d12 = _mm256_max_epi32(d05, d12);
        d05 = _mm256_min_epi32(d05, tmp);

        tmp = d13;
        
        d13 = _mm256_max_epi32(d04, d13);
        d04 = _mm256_min_epi32(d04, tmp);

        sort_08v_merge_ascending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_05v_merge_ascending(d09, d10, d11, d12, d13);
    }
    static INLINE void sort_13v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12, __m256i& d13) {
        __m256i  tmp;

        sort_08v_descending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_05v_ascending(d09, d10, d11, d12, d13);

        tmp = d09;
        
        d09 = _mm256_max_epi32(d08, d09);
        d08 = _mm256_min_epi32(d08, tmp);

        tmp = d10;
        
        d10 = _mm256_max_epi32(d07, d10);
        d07 = _mm256_min_epi32(d07, tmp);

        tmp = d11;
        
        d11 = _mm256_max_epi32(d06, d11);
        d06 = _mm256_min_epi32(d06, tmp);

        tmp = d12;
        
        d12 = _mm256_max_epi32(d05, d12);
        d05 = _mm256_min_epi32(d05, tmp);

        tmp = d13;
        
        d13 = _mm256_max_epi32(d04, d13);
        d04 = _mm256_min_epi32(d04, tmp);

        sort_08v_merge_descending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_05v_merge_descending(d09, d10, d11, d12, d13);
    }
    static INLINE void sort_14v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12, __m256i& d13, __m256i& d14) {
        __m256i  tmp;

        sort_08v_ascending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_06v_descending(d09, d10, d11, d12, d13, d14);

        tmp = d09;
        
        d09 = _mm256_max_epi32(d08, d09);
        d08 = _mm256_min_epi32(d08, tmp);

        tmp = d10;
        
        d10 = _mm256_max_epi32(d07, d10);
        d07 = _mm256_min_epi32(d07, tmp);

        tmp = d11;
        
        d11 = _mm256_max_epi32(d06, d11);
        d06 = _mm256_min_epi32(d06, tmp);

        tmp = d12;
        
        d12 = _mm256_max_epi32(d05, d12);
        d05 = _mm256_min_epi32(d05, tmp);

        tmp = d13;
        
        d13 = _mm256_max_epi32(d04, d13);
        d04 = _mm256_min_epi32(d04, tmp);

        tmp = d14;
        
        d14 = _mm256_max_epi32(d03, d14);
        d03 = _mm256_min_epi32(d03, tmp);

        sort_08v_merge_ascending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_06v_merge_ascending(d09, d10, d11, d12, d13, d14);
    }
    static INLINE void sort_14v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12, __m256i& d13, __m256i& d14) {
        __m256i  tmp;

        sort_08v_descending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_06v_ascending(d09, d10, d11, d12, d13, d14);

        tmp = d09;
        
        d09 = _mm256_max_epi32(d08, d09);
        d08 = _mm256_min_epi32(d08, tmp);

        tmp = d10;
        
        d10 = _mm256_max_epi32(d07, d10);
        d07 = _mm256_min_epi32(d07, tmp);

        tmp = d11;
        
        d11 = _mm256_max_epi32(d06, d11);
        d06 = _mm256_min_epi32(d06, tmp);

        tmp = d12;
        
        d12 = _mm256_max_epi32(d05, d12);
        d05 = _mm256_min_epi32(d05, tmp);

        tmp = d13;
        
        d13 = _mm256_max_epi32(d04, d13);
        d04 = _mm256_min_epi32(d04, tmp);

        tmp = d14;
        
        d14 = _mm256_max_epi32(d03, d14);
        d03 = _mm256_min_epi32(d03, tmp);

        sort_08v_merge_descending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_06v_merge_descending(d09, d10, d11, d12, d13, d14);
    }
    static INLINE void sort_15v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12, __m256i& d13, __m256i& d14, __m256i& d15) {
        __m256i  tmp;

        sort_08v_ascending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_07v_descending(d09, d10, d11, d12, d13, d14, d15);

        tmp = d09;
        
        d09 = _mm256_max_epi32(d08, d09);
        d08 = _mm256_min_epi32(d08, tmp);

        tmp = d10;
        
        d10 = _mm256_max_epi32(d07, d10);
        d07 = _mm256_min_epi32(d07, tmp);

        tmp = d11;
        
        d11 = _mm256_max_epi32(d06, d11);
        d06 = _mm256_min_epi32(d06, tmp);

        tmp = d12;
        
        d12 = _mm256_max_epi32(d05, d12);
        d05 = _mm256_min_epi32(d05, tmp);

        tmp = d13;
        
        d13 = _mm256_max_epi32(d04, d13);
        d04 = _mm256_min_epi32(d04, tmp);

        tmp = d14;
        
        d14 = _mm256_max_epi32(d03, d14);
        d03 = _mm256_min_epi32(d03, tmp);

        tmp = d15;
        
        d15 = _mm256_max_epi32(d02, d15);
        d02 = _mm256_min_epi32(d02, tmp);

        sort_08v_merge_ascending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_07v_merge_ascending(d09, d10, d11, d12, d13, d14, d15);
    }
    static INLINE void sort_15v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12, __m256i& d13, __m256i& d14, __m256i& d15) {
        __m256i  tmp;

        sort_08v_descending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_07v_ascending(d09, d10, d11, d12, d13, d14, d15);

        tmp = d09;
        
        d09 = _mm256_max_epi32(d08, d09);
        d08 = _mm256_min_epi32(d08, tmp);

        tmp = d10;
        
        d10 = _mm256_max_epi32(d07, d10);
        d07 = _mm256_min_epi32(d07, tmp);

        tmp = d11;
        
        d11 = _mm256_max_epi32(d06, d11);
        d06 = _mm256_min_epi32(d06, tmp);

        tmp = d12;
        
        d12 = _mm256_max_epi32(d05, d12);
        d05 = _mm256_min_epi32(d05, tmp);

        tmp = d13;
        
        d13 = _mm256_max_epi32(d04, d13);
        d04 = _mm256_min_epi32(d04, tmp);

        tmp = d14;
        
        d14 = _mm256_max_epi32(d03, d14);
        d03 = _mm256_min_epi32(d03, tmp);

        tmp = d15;
        
        d15 = _mm256_max_epi32(d02, d15);
        d02 = _mm256_min_epi32(d02, tmp);

        sort_08v_merge_descending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_07v_merge_descending(d09, d10, d11, d12, d13, d14, d15);
    }
    static NOINLINE void sort_16v_ascending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12, __m256i& d13, __m256i& d14, __m256i& d15, __m256i& d16) {
        __m256i  tmp;

        sort_08v_ascending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_08v_descending(d09, d10, d11, d12, d13, d14, d15, d16);

        tmp = d09;
        
        d09 = _mm256_max_epi32(d08, d09);
        d08 = _mm256_min_epi32(d08, tmp);

        tmp = d10;
        
        d10 = _mm256_max_epi32(d07, d10);
        d07 = _mm256_min_epi32(d07, tmp);

        tmp = d11;
        
        d11 = _mm256_max_epi32(d06, d11);
        d06 = _mm256_min_epi32(d06, tmp);

        tmp = d12;
        
        d12 = _mm256_max_epi32(d05, d12);
        d05 = _mm256_min_epi32(d05, tmp);

        tmp = d13;
        
        d13 = _mm256_max_epi32(d04, d13);
        d04 = _mm256_min_epi32(d04, tmp);

        tmp = d14;
        
        d14 = _mm256_max_epi32(d03, d14);
        d03 = _mm256_min_epi32(d03, tmp);

        tmp = d15;
        
        d15 = _mm256_max_epi32(d02, d15);
        d02 = _mm256_min_epi32(d02, tmp);

        tmp = d16;
        
        d16 = _mm256_max_epi32(d01, d16);
        d01 = _mm256_min_epi32(d01, tmp);

        sort_08v_merge_ascending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_08v_merge_ascending(d09, d10, d11, d12, d13, d14, d15, d16);
    }
    static NOINLINE void sort_16v_descending(__m256i& d01, __m256i& d02, __m256i& d03, __m256i& d04, __m256i& d05, __m256i& d06, __m256i& d07, __m256i& d08, __m256i& d09, __m256i& d10, __m256i& d11, __m256i& d12, __m256i& d13, __m256i& d14, __m256i& d15, __m256i& d16) {
        __m256i  tmp;

        sort_08v_descending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_08v_ascending(d09, d10, d11, d12, d13, d14, d15, d16);

        tmp = d09;
        
        d09 = _mm256_max_epi32(d08, d09);
        d08 = _mm256_min_epi32(d08, tmp);

        tmp = d10;
        
        d10 = _mm256_max_epi32(d07, d10);
        d07 = _mm256_min_epi32(d07, tmp);

        tmp = d11;
        
        d11 = _mm256_max_epi32(d06, d11);
        d06 = _mm256_min_epi32(d06, tmp);

        tmp = d12;
        
        d12 = _mm256_max_epi32(d05, d12);
        d05 = _mm256_min_epi32(d05, tmp);

        tmp = d13;
        
        d13 = _mm256_max_epi32(d04, d13);
        d04 = _mm256_min_epi32(d04, tmp);

        tmp = d14;
        
        d14 = _mm256_max_epi32(d03, d14);
        d03 = _mm256_min_epi32(d03, tmp);

        tmp = d15;
        
        d15 = _mm256_max_epi32(d02, d15);
        d02 = _mm256_min_epi32(d02, tmp);

        tmp = d16;
        
        d16 = _mm256_max_epi32(d01, d16);
        d01 = _mm256_min_epi32(d01, tmp);

        sort_08v_merge_descending(d01, d02, d03, d04, d05, d06, d07, d08);
        sort_08v_merge_descending(d09, d10, d11, d12, d13, d14, d15, d16);
    }

        static NOINLINE void sort_01v_alt(int32_t *ptr, int remainder) {
            const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N)));

        __m256i d01 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 0), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX)));
        sort_01v_ascending(d01);
        _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 0), mask, d01);
    }

        static NOINLINE void sort_02v_alt(int32_t *ptr, int remainder) {
            const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N)));

        __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);;
        __m256i d02 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 1), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX)));
        sort_02v_ascending(d01, d02);
        _mm256_storeu_si256((__m256i *) ptr + 0, d01);
        _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 1), mask, d02);
    }

        static NOINLINE void sort_03v_alt(int32_t *ptr, int remainder) {
            const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N)));

        __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);;
        __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);;
        __m256i d03 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 2), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX)));
        sort_03v_ascending(d01, d02, d03);
        _mm256_storeu_si256((__m256i *) ptr + 0, d01);
        _mm256_storeu_si256((__m256i *) ptr + 1, d02);
        _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 2), mask, d03);
    }

        static NOINLINE void sort_04v_alt(int32_t *ptr, int remainder) {
            const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N)));

        __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);;
        __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);;
        __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);;
        __m256i d04 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 3), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX)));
        sort_04v_ascending(d01, d02, d03, d04);
        _mm256_storeu_si256((__m256i *) ptr + 0, d01);
        _mm256_storeu_si256((__m256i *) ptr + 1, d02);
        _mm256_storeu_si256((__m256i *) ptr + 2, d03);
        _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 3), mask, d04);
    }

        static NOINLINE void sort_05v_alt(int32_t *ptr, int remainder) {
            const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N)));

        __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);;
        __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);;
        __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);;
        __m256i d04 = _mm256_lddqu_si256((__m256i const *) ptr + 3);;
        __m256i d05 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 4), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX)));
        sort_05v_ascending(d01, d02, d03, d04, d05);
        _mm256_storeu_si256((__m256i *) ptr + 0, d01);
        _mm256_storeu_si256((__m256i *) ptr + 1, d02);
        _mm256_storeu_si256((__m256i *) ptr + 2, d03);
        _mm256_storeu_si256((__m256i *) ptr + 3, d04);
        _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 4), mask, d05);
    }

        static NOINLINE void sort_06v_alt(int32_t *ptr, int remainder) {
            const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N)));

        __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);;
        __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);;
        __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);;
        __m256i d04 = _mm256_lddqu_si256((__m256i const *) ptr + 3);;
        __m256i d05 = _mm256_lddqu_si256((__m256i const *) ptr + 4);;
        __m256i d06 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 5), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX)));
        sort_06v_ascending(d01, d02, d03, d04, d05, d06);
        _mm256_storeu_si256((__m256i *) ptr + 0, d01);
        _mm256_storeu_si256((__m256i *) ptr + 1, d02);
        _mm256_storeu_si256((__m256i *) ptr + 2, d03);
        _mm256_storeu_si256((__m256i *) ptr + 3, d04);
        _mm256_storeu_si256((__m256i *) ptr + 4, d05);
        _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 5), mask, d06);
    }

        static NOINLINE void sort_07v_alt(int32_t *ptr, int remainder) {
            const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N)));

        __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);;
        __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);;
        __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);;
        __m256i d04 = _mm256_lddqu_si256((__m256i const *) ptr + 3);;
        __m256i d05 = _mm256_lddqu_si256((__m256i const *) ptr + 4);;
        __m256i d06 = _mm256_lddqu_si256((__m256i const *) ptr + 5);;
        __m256i d07 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 6), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX)));
        sort_07v_ascending(d01, d02, d03, d04, d05, d06, d07);
        _mm256_storeu_si256((__m256i *) ptr + 0, d01);
        _mm256_storeu_si256((__m256i *) ptr + 1, d02);
        _mm256_storeu_si256((__m256i *) ptr + 2, d03);
        _mm256_storeu_si256((__m256i *) ptr + 3, d04);
        _mm256_storeu_si256((__m256i *) ptr + 4, d05);
        _mm256_storeu_si256((__m256i *) ptr + 5, d06);
        _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 6), mask, d07);
    }

        static NOINLINE void sort_08v_alt(int32_t *ptr, int remainder) {
            const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N)));

        __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);;
        __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);;
        __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);;
        __m256i d04 = _mm256_lddqu_si256((__m256i const *) ptr + 3);;
        __m256i d05 = _mm256_lddqu_si256((__m256i const *) ptr + 4);;
        __m256i d06 = _mm256_lddqu_si256((__m256i const *) ptr + 5);;
        __m256i d07 = _mm256_lddqu_si256((__m256i const *) ptr + 6);;
        __m256i d08 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 7), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX)));
        sort_08v_ascending(d01, d02, d03, d04, d05, d06, d07, d08);
        _mm256_storeu_si256((__m256i *) ptr + 0, d01);
        _mm256_storeu_si256((__m256i *) ptr + 1, d02);
        _mm256_storeu_si256((__m256i *) ptr + 2, d03);
        _mm256_storeu_si256((__m256i *) ptr + 3, d04);
        _mm256_storeu_si256((__m256i *) ptr + 4, d05);
        _mm256_storeu_si256((__m256i *) ptr + 5, d06);
        _mm256_storeu_si256((__m256i *) ptr + 6, d07);
        _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 7), mask, d08);
    }

        static NOINLINE void sort_09v_alt(int32_t *ptr, int remainder) {
            const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N)));

        __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);;
        __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);;
        __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);;
        __m256i d04 = _mm256_lddqu_si256((__m256i const *) ptr + 3);;
        __m256i d05 = _mm256_lddqu_si256((__m256i const *) ptr + 4);;
        __m256i d06 = _mm256_lddqu_si256((__m256i const *) ptr + 5);;
        __m256i d07 = _mm256_lddqu_si256((__m256i const *) ptr + 6);;
        __m256i d08 = _mm256_lddqu_si256((__m256i const *) ptr + 7);;
        __m256i d09 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 8), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX)));
        sort_09v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09);
        _mm256_storeu_si256((__m256i *) ptr + 0, d01);
        _mm256_storeu_si256((__m256i *) ptr + 1, d02);
        _mm256_storeu_si256((__m256i *) ptr + 2, d03);
        _mm256_storeu_si256((__m256i *) ptr + 3, d04);
        _mm256_storeu_si256((__m256i *) ptr + 4, d05);
        _mm256_storeu_si256((__m256i *) ptr + 5, d06);
        _mm256_storeu_si256((__m256i *) ptr + 6, d07);
        _mm256_storeu_si256((__m256i *) ptr + 7, d08);
        _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 8), mask, d09);
    }

        static NOINLINE void sort_10v_alt(int32_t *ptr, int remainder) {
            const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N)));

        __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);;
        __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);;
        __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);;
        __m256i d04 = _mm256_lddqu_si256((__m256i const *) ptr + 3);;
        __m256i d05 = _mm256_lddqu_si256((__m256i const *) ptr + 4);;
        __m256i d06 = _mm256_lddqu_si256((__m256i const *) ptr + 5);;
        __m256i d07 = _mm256_lddqu_si256((__m256i const *) ptr + 6);;
        __m256i d08 = _mm256_lddqu_si256((__m256i const *) ptr + 7);;
        __m256i d09 = _mm256_lddqu_si256((__m256i const *) ptr + 8);;
        __m256i d10 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 9), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX)));
        sort_10v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10);
        _mm256_storeu_si256((__m256i *) ptr + 0, d01);
        _mm256_storeu_si256((__m256i *) ptr + 1, d02);
        _mm256_storeu_si256((__m256i *) ptr + 2, d03);
        _mm256_storeu_si256((__m256i *) ptr + 3, d04);
        _mm256_storeu_si256((__m256i *) ptr + 4, d05);
        _mm256_storeu_si256((__m256i *) ptr + 5, d06);
        _mm256_storeu_si256((__m256i *) ptr + 6, d07);
        _mm256_storeu_si256((__m256i *) ptr + 7, d08);
        _mm256_storeu_si256((__m256i *) ptr + 8, d09);
        _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 9), mask, d10);
    }

        static NOINLINE void sort_11v_alt(int32_t *ptr, int remainder) {
            const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N)));

        __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);;
        __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);;
        __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);;
        __m256i d04 = _mm256_lddqu_si256((__m256i const *) ptr + 3);;
        __m256i d05 = _mm256_lddqu_si256((__m256i const *) ptr + 4);;
        __m256i d06 = _mm256_lddqu_si256((__m256i const *) ptr + 5);;
        __m256i d07 = _mm256_lddqu_si256((__m256i const *) ptr + 6);;
        __m256i d08 = _mm256_lddqu_si256((__m256i const *) ptr + 7);;
        __m256i d09 = _mm256_lddqu_si256((__m256i const *) ptr + 8);;
        __m256i d10 = _mm256_lddqu_si256((__m256i const *) ptr + 9);;
        __m256i d11 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 10), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX)));
        sort_11v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11);
        _mm256_storeu_si256((__m256i *) ptr + 0, d01);
        _mm256_storeu_si256((__m256i *) ptr + 1, d02);
        _mm256_storeu_si256((__m256i *) ptr + 2, d03);
        _mm256_storeu_si256((__m256i *) ptr + 3, d04);
        _mm256_storeu_si256((__m256i *) ptr + 4, d05);
        _mm256_storeu_si256((__m256i *) ptr + 5, d06);
        _mm256_storeu_si256((__m256i *) ptr + 6, d07);
        _mm256_storeu_si256((__m256i *) ptr + 7, d08);
        _mm256_storeu_si256((__m256i *) ptr + 8, d09);
        _mm256_storeu_si256((__m256i *) ptr + 9, d10);
        _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 10), mask, d11);
    }

        static NOINLINE void sort_12v_alt(int32_t *ptr, int remainder) {
            const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N)));

        __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);;
        __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);;
        __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);;
        __m256i d04 = _mm256_lddqu_si256((__m256i const *) ptr + 3);;
        __m256i d05 = _mm256_lddqu_si256((__m256i const *) ptr + 4);;
        __m256i d06 = _mm256_lddqu_si256((__m256i const *) ptr + 5);;
        __m256i d07 = _mm256_lddqu_si256((__m256i const *) ptr + 6);;
        __m256i d08 = _mm256_lddqu_si256((__m256i const *) ptr + 7);;
        __m256i d09 = _mm256_lddqu_si256((__m256i const *) ptr + 8);;
        __m256i d10 = _mm256_lddqu_si256((__m256i const *) ptr + 9);;
        __m256i d11 = _mm256_lddqu_si256((__m256i const *) ptr + 10);;
        __m256i d12 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 11), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX)));
        sort_12v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12);
        _mm256_storeu_si256((__m256i *) ptr + 0, d01);
        _mm256_storeu_si256((__m256i *) ptr + 1, d02);
        _mm256_storeu_si256((__m256i *) ptr + 2, d03);
        _mm256_storeu_si256((__m256i *) ptr + 3, d04);
        _mm256_storeu_si256((__m256i *) ptr + 4, d05);
        _mm256_storeu_si256((__m256i *) ptr + 5, d06);
        _mm256_storeu_si256((__m256i *) ptr + 6, d07);
        _mm256_storeu_si256((__m256i *) ptr + 7, d08);
        _mm256_storeu_si256((__m256i *) ptr + 8, d09);
        _mm256_storeu_si256((__m256i *) ptr + 9, d10);
        _mm256_storeu_si256((__m256i *) ptr + 10, d11);
        _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 11), mask, d12);
    }

        static NOINLINE void sort_13v_alt(int32_t *ptr, int remainder) {
            const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N)));

        __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);;
        __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);;
        __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);;
        __m256i d04 = _mm256_lddqu_si256((__m256i const *) ptr + 3);;
        __m256i d05 = _mm256_lddqu_si256((__m256i const *) ptr + 4);;
        __m256i d06 = _mm256_lddqu_si256((__m256i const *) ptr + 5);;
        __m256i d07 = _mm256_lddqu_si256((__m256i const *) ptr + 6);;
        __m256i d08 = _mm256_lddqu_si256((__m256i const *) ptr + 7);;
        __m256i d09 = _mm256_lddqu_si256((__m256i const *) ptr + 8);;
        __m256i d10 = _mm256_lddqu_si256((__m256i const *) ptr + 9);;
        __m256i d11 = _mm256_lddqu_si256((__m256i const *) ptr + 10);;
        __m256i d12 = _mm256_lddqu_si256((__m256i const *) ptr + 11);;
        __m256i d13 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 12), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX)));
        sort_13v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12, d13);
        _mm256_storeu_si256((__m256i *) ptr + 0, d01);
        _mm256_storeu_si256((__m256i *) ptr + 1, d02);
        _mm256_storeu_si256((__m256i *) ptr + 2, d03);
        _mm256_storeu_si256((__m256i *) ptr + 3, d04);
        _mm256_storeu_si256((__m256i *) ptr + 4, d05);
        _mm256_storeu_si256((__m256i *) ptr + 5, d06);
        _mm256_storeu_si256((__m256i *) ptr + 6, d07);
        _mm256_storeu_si256((__m256i *) ptr + 7, d08);
        _mm256_storeu_si256((__m256i *) ptr + 8, d09);
        _mm256_storeu_si256((__m256i *) ptr + 9, d10);
        _mm256_storeu_si256((__m256i *) ptr + 10, d11);
        _mm256_storeu_si256((__m256i *) ptr + 11, d12);
        _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 12), mask, d13);
    }

        static NOINLINE void sort_14v_alt(int32_t *ptr, int remainder) {
            const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N)));

        __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);;
        __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);;
        __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);;
        __m256i d04 = _mm256_lddqu_si256((__m256i const *) ptr + 3);;
        __m256i d05 = _mm256_lddqu_si256((__m256i const *) ptr + 4);;
        __m256i d06 = _mm256_lddqu_si256((__m256i const *) ptr + 5);;
        __m256i d07 = _mm256_lddqu_si256((__m256i const *) ptr + 6);;
        __m256i d08 = _mm256_lddqu_si256((__m256i const *) ptr + 7);;
        __m256i d09 = _mm256_lddqu_si256((__m256i const *) ptr + 8);;
        __m256i d10 = _mm256_lddqu_si256((__m256i const *) ptr + 9);;
        __m256i d11 = _mm256_lddqu_si256((__m256i const *) ptr + 10);;
        __m256i d12 = _mm256_lddqu_si256((__m256i const *) ptr + 11);;
        __m256i d13 = _mm256_lddqu_si256((__m256i const *) ptr + 12);;
        __m256i d14 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 13), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX)));
        sort_14v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12, d13, d14);
        _mm256_storeu_si256((__m256i *) ptr + 0, d01);
        _mm256_storeu_si256((__m256i *) ptr + 1, d02);
        _mm256_storeu_si256((__m256i *) ptr + 2, d03);
        _mm256_storeu_si256((__m256i *) ptr + 3, d04);
        _mm256_storeu_si256((__m256i *) ptr + 4, d05);
        _mm256_storeu_si256((__m256i *) ptr + 5, d06);
        _mm256_storeu_si256((__m256i *) ptr + 6, d07);
        _mm256_storeu_si256((__m256i *) ptr + 7, d08);
        _mm256_storeu_si256((__m256i *) ptr + 8, d09);
        _mm256_storeu_si256((__m256i *) ptr + 9, d10);
        _mm256_storeu_si256((__m256i *) ptr + 10, d11);
        _mm256_storeu_si256((__m256i *) ptr + 11, d12);
        _mm256_storeu_si256((__m256i *) ptr + 12, d13);
        _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 13), mask, d14);
    }

        static NOINLINE void sort_15v_alt(int32_t *ptr, int remainder) {
            const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N)));

        __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);;
        __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);;
        __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);;
        __m256i d04 = _mm256_lddqu_si256((__m256i const *) ptr + 3);;
        __m256i d05 = _mm256_lddqu_si256((__m256i const *) ptr + 4);;
        __m256i d06 = _mm256_lddqu_si256((__m256i const *) ptr + 5);;
        __m256i d07 = _mm256_lddqu_si256((__m256i const *) ptr + 6);;
        __m256i d08 = _mm256_lddqu_si256((__m256i const *) ptr + 7);;
        __m256i d09 = _mm256_lddqu_si256((__m256i const *) ptr + 8);;
        __m256i d10 = _mm256_lddqu_si256((__m256i const *) ptr + 9);;
        __m256i d11 = _mm256_lddqu_si256((__m256i const *) ptr + 10);;
        __m256i d12 = _mm256_lddqu_si256((__m256i const *) ptr + 11);;
        __m256i d13 = _mm256_lddqu_si256((__m256i const *) ptr + 12);;
        __m256i d14 = _mm256_lddqu_si256((__m256i const *) ptr + 13);;
        __m256i d15 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 14), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX)));
        sort_15v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12, d13, d14, d15);
        _mm256_storeu_si256((__m256i *) ptr + 0, d01);
        _mm256_storeu_si256((__m256i *) ptr + 1, d02);
        _mm256_storeu_si256((__m256i *) ptr + 2, d03);
        _mm256_storeu_si256((__m256i *) ptr + 3, d04);
        _mm256_storeu_si256((__m256i *) ptr + 4, d05);
        _mm256_storeu_si256((__m256i *) ptr + 5, d06);
        _mm256_storeu_si256((__m256i *) ptr + 6, d07);
        _mm256_storeu_si256((__m256i *) ptr + 7, d08);
        _mm256_storeu_si256((__m256i *) ptr + 8, d09);
        _mm256_storeu_si256((__m256i *) ptr + 9, d10);
        _mm256_storeu_si256((__m256i *) ptr + 10, d11);
        _mm256_storeu_si256((__m256i *) ptr + 11, d12);
        _mm256_storeu_si256((__m256i *) ptr + 12, d13);
        _mm256_storeu_si256((__m256i *) ptr + 13, d14);
        _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 14), mask, d15);
    }

        static NOINLINE void sort_16v_alt(int32_t *ptr, int remainder) {
            const auto mask = _mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)(mask_table_8 + remainder * N)));

        __m256i d01 = _mm256_lddqu_si256((__m256i const *) ptr + 0);;
        __m256i d02 = _mm256_lddqu_si256((__m256i const *) ptr + 1);;
        __m256i d03 = _mm256_lddqu_si256((__m256i const *) ptr + 2);;
        __m256i d04 = _mm256_lddqu_si256((__m256i const *) ptr + 3);;
        __m256i d05 = _mm256_lddqu_si256((__m256i const *) ptr + 4);;
        __m256i d06 = _mm256_lddqu_si256((__m256i const *) ptr + 5);;
        __m256i d07 = _mm256_lddqu_si256((__m256i const *) ptr + 6);;
        __m256i d08 = _mm256_lddqu_si256((__m256i const *) ptr + 7);;
        __m256i d09 = _mm256_lddqu_si256((__m256i const *) ptr + 8);;
        __m256i d10 = _mm256_lddqu_si256((__m256i const *) ptr + 9);;
        __m256i d11 = _mm256_lddqu_si256((__m256i const *) ptr + 10);;
        __m256i d12 = _mm256_lddqu_si256((__m256i const *) ptr + 11);;
        __m256i d13 = _mm256_lddqu_si256((__m256i const *) ptr + 12);;
        __m256i d14 = _mm256_lddqu_si256((__m256i const *) ptr + 13);;
        __m256i d15 = _mm256_lddqu_si256((__m256i const *) ptr + 14);;
        __m256i d16 = _mm256_or_si256(_mm256_maskload_epi32((int32_t const *) ((__m256i const *) ptr + 15), mask), _mm256_andnot_si256(mask, _mm256_set1_epi32(MAX)));
        sort_16v_ascending(d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12, d13, d14, d15, d16);
        _mm256_storeu_si256((__m256i *) ptr + 0, d01);
        _mm256_storeu_si256((__m256i *) ptr + 1, d02);
        _mm256_storeu_si256((__m256i *) ptr + 2, d03);
        _mm256_storeu_si256((__m256i *) ptr + 3, d04);
        _mm256_storeu_si256((__m256i *) ptr + 4, d05);
        _mm256_storeu_si256((__m256i *) ptr + 5, d06);
        _mm256_storeu_si256((__m256i *) ptr + 6, d07);
        _mm256_storeu_si256((__m256i *) ptr + 7, d08);
        _mm256_storeu_si256((__m256i *) ptr + 8, d09);
        _mm256_storeu_si256((__m256i *) ptr + 9, d10);
        _mm256_storeu_si256((__m256i *) ptr + 10, d11);
        _mm256_storeu_si256((__m256i *) ptr + 11, d12);
        _mm256_storeu_si256((__m256i *) ptr + 12, d13);
        _mm256_storeu_si256((__m256i *) ptr + 13, d14);
        _mm256_storeu_si256((__m256i *) ptr + 14, d15);
        _mm256_maskstore_epi32((int32_t *) ((__m256i *) ptr + 15), mask, d16);
    }
    static void sort(int32_t *ptr, size_t length);

};
}
}

#undef i2d
#undef d2i
#undef i2s
#undef s2i
#undef s2d
#undef d2s

#ifdef __GNUC__
#ifdef __clang__
#pragma clang attribute pop
#else
#pragma GCC pop_options
#endif
#endif
#endif
    
